Análisis Inicial vs Exploratorio de Datos

R para Ciencia de Datos en Salud:
Análisis Descriptivo e Inferencia Estadística

Percy Soto-Becerra M.D., M.Sc(c)

InkaStats Data Science Solutions | Medical Branch
@github/psotob91

Análisis Exploratorio de Datos versus Análisis Inicial de Datos



El análisis inicial de datos y el análisis exploratorio de datos son dos cosas diferentes!!

Análisis Exploratorio de Datos


Análisis Exploratorio de Datos

  • El AED es un enfoque de análisis de conjunto de datos para identificar patrones y formular nuevas hipótesis.

  • Se trata de ver qué nos dice los datos más allá de ideas pre-concebidas.

  • Las nuevas hipótesis luego se confirman en otros nuevos estudios rigurosos.

  • Su versión moderna: Minería de Datos (Data Minning)

Análisis Inicial de Datos

  • El AID, a menudo, se confunde erróneamente con el AED:

    • Ambos son dos enfoques totalmente diferentes que comparten herramietnas comunes.
  • Objetivo del AID:

“(…) garantizar principalmente la transparencia y la integridad de las condiciones previas para realizar análisis estadísticos apropiados de manera responsable para responder preguntas de investigación predefinidas.”
Baillie M, et al. [PLoS Comput Biol, 2022]
(https://doi.org/10.1371/journal.pcbi.1009819)

Análisis Inicial de Datos vs. Análisis Exploratorio de Datos


AID AED
1. AID es el paso inicial del proceso de confirmación de hipótesis pre-definidas. 1. AED busca generar hipótesis nuevas.
2. En investigación clínico-epidemiológica, a menudo queremos y deberíamos hacer AID. 2. Rara vez queremos AED (p. ej., enfermedades nuevas, fenómenos muy poco conocidos)
3. Proceso clave para garantizar responder adecuadamente objetivos pre-planeados de estudio. 3. Proceso con alto riesgo de contaminar respuesta a objetivos pre-planeados de estudio.

Mala práctica: ¡Hacer AED en vez de AID!


  • A menudo, investigadores no realizan AID de manera sistemática.

  • Mezclan actividades de AID con tareas posteriores de análisis de datos, como generación o exploración de hipótesis, análisis formal e interpretación de conclusiones.

  • Como se hacen “informalmente”, no se reportan en detalle generándose análisis ocultos.

  • Estos análisis ocultos generan problemas en la reproducibilidad de los estudios.

  • Generan muchos grados de libertad adicionales ocasionando problemas serios de validez de los análisis: p-hacking, post-selection inference, double-dipping, overfitting, etc.

  • Iniciativa STRATOS ha dado pautas para realizar AID apropiados.

El problema de los análisis ocultos

BMC Med Res Methodol 20, 61 (2020)

Recomendaciones de STRATOS para hacer un buen AID

PLoS Comput Biol 18(2): e1009819

AID es un proceso iterativo


  • Proceso no lineal, al contrario, requiere muchas iteraciones.

  • Riesgo: Puede influir en análisis e inducir conclusiones erróneas.

    • Mayor riesgo de restultados falsos positivos.
  • Ser cuidados para:

    • Evitar alterar la pregunta de investigación.
    • Proveer documentación completa del proceso.

AID como parte del plan de investigación

Introducing the Initial Data Analysis Topic Group (TG3)

AID como parte del plan de investigación

Huebner M, Vach W, et al.

10 recomendaciones de STRATOS para un buen AID


  • Regla 1: Desarrolle un plan de AID que respalde el objetivo de la investigación.

  • Regla 2: AID toma tiempo y recursos.

  • Regla 3: AID debe ser reproducible.

  • Regla 4: El contexto importa, conoce tus datos.

  • Regla 5: Evite los adelantos, AID no toca la pregunta de investigación.

  • Regla 6: Visualiza tus datos.

  • Regla 7: Compruebe lo que falte.

  • Regla 8: Comunicar los hallazgos y considerar las consecuencias.

  • Regla 9: Reporte los hallazgos del AID en trabajos de investigación (¡adjunte anexos!)

  • Regla 10: Sea proactivo y riguroso.

10 recomendaciones de STRATOS para un buen AID


  • Regla 1: Desarrolle un plan de AID que respalde el objetivo de la investigación ¡Escríbalo en el proyecto o anexe un plan de análisis estadístico detallado!

  • Regla 2: AID toma tiempo y recursos. Presupueste RRHH y tiempo razonable

  • Regla 3: AID debe ser reproducible. Use programas que generen código

  • Regla 4: El contexto importa, conoce tus datos. {dplyr} en R

  • Regla 5: Evite los adelantos, AID no toca la pregunta de investigación. ¡No haga ’análisis perliminar` sin antes inspeccionar y limpiar bien lso datos!

  • Regla 6: Visualiza tus datos. {ggplot2} en R

  • Regla 7: Compruebe lo que falte. {tidyverse} para queries en R

  • Regla 8: Comunicar los hallazgos y considerar las consecuencias. Quarto para programación literaria en R

  • Regla 9: Reporte los hallazgos del AID en trabajos de investigación (¡adjunte anexos!). Ídem

  • Regla 10: Sea proactivo y riguroso. ¡Los datos son como sus pacientes, use las mejores técnicas y herramientas disponibles!

Regla 4: El contexto importa, conoce tus datos


  • Dé una primera mirada global a los datos
  • Diseñe una lista de validaciones a realizar desde el proyecto.
  • Valida tus datos:
    • Identifique duplicados y detecte inconsistencias
    • Valores extremos no plausibles
    • Identifique valores perdidos
  • En R, use los verbos básicos de {dplyr} para hacer consultas (“queries”) a sus datos: filter(), select(), mutate(), arrange() y summarise().

Pasos para un buen AID / AED

Paso 1: Resumen global de los datos

  • Dimensiones: columnas y filas

  • Variables y tipos

  • Datos completos y faltantes

  • Variables numéricas: Mínimos, máximos y valores extremos

  • Variables categóricas: Valores o categorías muy poco frecuentes y datos perdidos encubiertos

  • Heche un vistazo de los datos con glimpse():
glimpse(datos)
Rows: 26
Columns: 13
$ id_jaula     <dbl> 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 5, 5, 5, 5, 8, 8, 9, 9, 9, …
$ id_raton     <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17…
$ tratamiento  <chr> "control", "control", "control", "control", "control", "m…
$ protocolo    <chr> "ovx", "ovx", "ovx", "hemiovx", "ovx", "ovx", "ovx", "ovx…
$ peso_inicial <dbl> 26.00, 24.50, 20.40, 26.59, 23.50, 25.00, 24.80, 23.20, 2…
$ peso_final   <dbl> 33.28, 30.50, 29.93, 32.19, 30.37, 30.43, 28.77, 27.30, 2…
$ peso_utero   <dbl> 0.089, 0.063, 0.078, 0.134, 0.052, 0.055, 0.064, 0.062, 0…
$ chol         <dbl> 85.990, 94.460, 99.670, 83.380, 82.080, 107.490, 76.870, …
$ glucose      <dbl> 109.97, 81.62, 118.37, 71.91, 95.53, 160.36, 195.53, 182.…
$ tag          <dbl> 182.42, 211.87, 195.16, 98.46, 108.13, 141.10, 95.82, 105…
$ prot         <dbl> 5.37, 4.68, NA, NA, 5.33, NA, 5.02, 6.12, NA, 4.85, NA, N…
$ urea         <dbl> 66.27, 76.73, 52.32, 50.71, 26.02, NA, 40.78, 66.94, NA, …
$ album        <dbl> 66.82, 55.36, NA, NA, NA, 72.14, 67.09, 70.64, 66.27, 83.…
  • La función skim() del paquete [skim]r]{.plo} genera un resumen global de los datos:
skim(datos)
Data summary
Name datos
Number of rows 26
Number of columns 13
_______________________
Column type frequency:
character 2
numeric 11
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
tratamiento 0 1 4 25 0 5 0
protocolo 0 1 3 7 0 3 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id_jaula 0 1.00 4.92 3.36 1.00 2.00 4.00 8.75 10.00 ▇▃▃▂▆
id_raton 0 1.00 11.19 6.85 1.00 5.25 10.50 16.75 23.00 ▇▆▆▅▆
peso_inicial 0 1.00 23.72 1.93 18.90 22.69 23.50 24.95 27.90 ▂▃▇▆▂
peso_final 0 1.00 28.77 2.30 23.80 26.97 28.77 30.34 33.28 ▂▇▇▆▃
peso_utero 0 1.00 0.09 0.10 0.01 0.06 0.07 0.09 0.54 ▇▁▁▁▁
chol 0 1.00 82.25 12.13 59.28 74.91 82.73 85.99 107.49 ▃▃▇▂▂
glucose 0 1.00 125.35 37.52 60.10 97.30 116.53 148.82 195.53 ▃▇▆▃▅
tag 0 1.00 150.08 51.70 90.99 108.13 137.80 184.39 282.64 ▇▂▅▁▁
prot 12 0.54 5.24 0.45 4.68 4.93 5.24 5.36 6.17 ▇▃▇▁▃
urea 10 0.62 55.60 31.21 26.02 38.16 48.16 66.27 157.89 ▇▃▁▁▁
album 13 0.50 66.21 7.71 52.77 64.64 66.82 68.59 83.73 ▂▂▇▁▁
  • La función describe() del paquete Hmisc genera un reporte general bien detallado, variable por variable:
describe(datos)
datos 

 13  Variables      26  Observations
--------------------------------------------------------------------------------
id_jaula : ID de jaula 
       n  missing distinct     Info     Mean      Gmd 
      26        0        7    0.978    4.923    3.815 

lowest :  1  2  3  5  8, highest:  3  5  8  9 10
                                                    
Value          1     2     3     5     8     9    10
Frequency      4     5     4     4     2     4     3
Proportion 0.154 0.192 0.154 0.154 0.077 0.154 0.115
--------------------------------------------------------------------------------
id_raton : ID de ratón 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      26        0       23    0.999    11.19    8.046     1.25     2.50 
     .25      .50      .75      .90      .95 
    5.25    10.50    16.75    20.50    21.75 

lowest :  1  2  3  4  5, highest: 19 20 21 22 23
--------------------------------------------------------------------------------
tratamiento : Tratamiento asignado 
       n  missing distinct 
      26        0        5 

lowest : control                   maca                      maca + critro             sham operated             triple dosis maca + citro
highest: control                   maca                      maca + critro             sham operated             triple dosis maca + citro

control (7, 0.269), maca (6, 0.231), maca + critro (4, 0.154), sham operated
(4, 0.154), triple dosis maca + citro (5, 0.192)
--------------------------------------------------------------------------------
protocolo : Tipo de protocolo de modelo animal 
       n  missing distinct 
      26        0        3 
                                  
Value      hemiovx  no ovx     ovx
Frequency        3       4      19
Proportion   0.115   0.154   0.731
--------------------------------------------------------------------------------
peso_inicial : Peso inicial 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      26        0       19    0.997    23.72    2.171    20.77    21.90 
     .25      .50      .75      .90      .95 
   22.69    23.50    24.95    26.00    26.44 

lowest : 18.90 20.40 21.90 22.40 22.50, highest: 25.30 25.50 26.00 26.59 27.90
                                                                            
Value      18.90 20.40 21.90 22.40 22.50 22.69 22.90 23.20 23.40 23.50 23.90
Frequency      1     1     2     1     1     2     1     1     2     3     1
Proportion 0.038 0.038 0.077 0.038 0.038 0.077 0.038 0.038 0.077 0.115 0.038
                                                          
Value      24.50 24.80 25.00 25.30 25.50 26.00 26.59 27.90
Frequency      2     1     1     1     1     2     1     1
Proportion 0.077 0.038 0.038 0.038 0.038 0.077 0.038 0.038
--------------------------------------------------------------------------------
peso_final : Peso final 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      26        0       21    0.998    28.77    2.616    25.37    26.69 
     .25      .50      .75      .90      .95 
   26.97    28.77    30.34    31.34    33.01 

lowest : 23.80 24.93 26.68 26.70 26.86, highest: 30.37 30.43 30.50 32.19 33.28
--------------------------------------------------------------------------------
peso_utero : Peso uterino 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      26        0       23    0.999  0.09012  0.07069  0.01750  0.03400 
     .25      .50      .75      .90      .95 
 0.05550  0.06900  0.08875  0.12350  0.16550 

lowest : 0.014 0.016 0.022 0.046 0.052, highest: 0.108 0.113 0.134 0.176 0.535
--------------------------------------------------------------------------------
chol : Colesterol 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      26        0       21    0.997    82.25     13.8    64.75    66.44 
     .25      .50      .75      .90      .95 
   74.91    82.73    85.99    97.72   103.58 

lowest :  59.28  64.40  65.79  67.10  68.40, highest:  94.46  95.76  99.67 104.88 107.49
--------------------------------------------------------------------------------
glucose : Glucosa 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      26        0       23    0.999    125.3    43.48    73.49    79.92 
     .25      .50      .75      .90      .95 
   97.30   116.53   148.82   183.46   184.51 

lowest :  60.10  71.91  78.22  81.62  94.23, highest: 160.36 168.50 182.41 184.51 195.53
--------------------------------------------------------------------------------
tag : Triglicéridos 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      26        0       22    0.998    150.1     58.3    91.54    94.50 
     .25      .50      .75      .90      .95 
  108.13   137.81   184.39   205.94   236.60 

lowest :  90.99  93.19  95.82  98.46 105.49, highest: 199.12 200.00 211.87 244.84 282.64
--------------------------------------------------------------------------------
prot : Proteína 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      14       12       10    0.987     5.24   0.4943    4.745    4.801 
     .25      .50      .75      .90      .95 
   4.930    5.240    5.360    5.895    6.138 

lowest : 4.68 4.78 4.85 4.93 5.02, highest: 5.15 5.33 5.37 6.12 6.17
                                                                      
Value       4.68  4.78  4.85  4.93  5.02  5.15  5.33  5.37  6.12  6.17
Frequency      1     1     1     2     1     1     3     2     1     1
Proportion 0.071 0.071 0.071 0.143 0.071 0.071 0.214 0.143 0.071 0.071
--------------------------------------------------------------------------------
urea : Urea 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      16       10       14    0.997     55.6     29.8    26.02    30.25 
     .25      .50      .75      .90      .95 
   38.16    48.16    66.27    71.84    97.02 

lowest :  26.02  34.48  37.96  38.23  40.78, highest:  60.37  66.27  66.94  76.73 157.89
                                                                         
Value       26.02  34.48  37.96  38.23  40.78  43.06  45.61  50.71  52.32
Frequency       2      1      1      1      1      1      1      1      1
Proportion  0.125  0.062  0.062  0.062  0.062  0.062  0.062  0.062  0.062
                                             
Value       60.37  66.27  66.94  76.73 157.89
Frequency       1      2      1      1      1
Proportion  0.062  0.125  0.062  0.062  0.062
--------------------------------------------------------------------------------
album : Albuminemia 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      13       13       11    0.995    66.21    8.408    54.32    56.21 
     .25      .50      .75      .90      .95 
   64.64    66.82    68.59    71.84    76.78 

lowest : 52.77 55.36 59.59 64.64 66.27, highest: 67.09 68.59 70.64 72.14 83.73
                                                                            
Value      52.77 55.36 59.59 64.64 66.27 66.82 67.09 68.59 70.64 72.14 83.73
Frequency      1     1     1     1     2     2     1     1     1     1     1
Proportion 0.077 0.077 0.077 0.077 0.154 0.154 0.077 0.077 0.077 0.077 0.077
--------------------------------------------------------------------------------

Paso 2: Detecte y maneje duplicados

  • Función get_dupes del paquete {janitor}.
  • Si solo colocamos get_dupes(), entonces nos identifica duplicados de fila completa:
library(janitor)
datos %>% 
  get_dupes()
  id_jaula id_raton tratamiento protocolo peso_inicial peso_final peso_utero
1        1        1     control       ovx        26.00      33.28      0.089
2        1        1     control       ovx        26.00      33.28      0.089
3        2        5     control       ovx        23.50      30.37      0.052
4        2        5     control       ovx        23.50      30.37      0.052
5        3        9        maca   hemiovx        22.69      26.86      0.070
6        3        9        maca   hemiovx        22.69      26.86      0.070
   chol glucose    tag prot  urea album dupe_count
1 85.99  109.97 182.42 5.37 66.27 66.82          2
2 85.99  109.97 182.42 5.37 66.27 66.82          2
3 82.08   95.53 108.13 5.33 26.02    NA          2
4 82.08   95.53 108.13 5.33 26.02    NA          2
5 85.34  184.51  90.99   NA    NA 66.27          2
6 85.34  184.51  90.99   NA    NA 66.27          2
  • Si colocamos una o más variables dentro de get_dupes(), entonces nos identifica duplicados solo de esa variable.

  • A menudo lo hacemos para encontrar individus duplicados.

datos %>% 
  get_dupes(id_raton)
  id_raton dupe_count id_jaula tratamiento protocolo peso_inicial peso_final
1        1          2        1     control       ovx        26.00      33.28
2        1          2        1     control       ovx        26.00      33.28
3        5          2        2     control       ovx        23.50      30.37
4        5          2        2     control       ovx        23.50      30.37
5        9          2        3        maca   hemiovx        22.69      26.86
6        9          2        3        maca   hemiovx        22.69      26.86
  peso_utero  chol glucose    tag prot  urea album
1      0.089 85.99  109.97 182.42 5.37 66.27 66.82
2      0.089 85.99  109.97 182.42 5.37 66.27 66.82
3      0.052 82.08   95.53 108.13 5.33 26.02    NA
4      0.052 82.08   95.53 108.13 5.33 26.02    NA
5      0.070 85.34  184.51  90.99   NA    NA 66.27
6      0.070 85.34  184.51  90.99   NA    NA 66.27
  • Si el duplicado es erróneo, lo podemos eliminar con distinct y el argumento .keep_all = TRUE.

  • Se debde espeficiar si el duplicado es de fila o de alguna variable (p. ej., id).

datos <- datos %>% 
  distinct(id_raton, .keep_all = TRUE)

datos
   id_jaula id_raton               tratamiento protocolo peso_inicial
1         1        1                   control       ovx        26.00
2         1        2                   control       ovx        24.50
3         1        3                   control       ovx        20.40
4         2        4                   control   hemiovx        26.59
5         2        5                   control       ovx        23.50
6         2        6                      maca       ovx        25.00
7         2        7                      maca       ovx        24.80
8         3        8                      maca       ovx        23.20
9         3        9                      maca   hemiovx        22.69
10        3       10                      maca       ovx        23.90
11        5       11             maca + critro       ovx        21.90
12        5       12             maca + critro       ovx        23.40
13        5       13             maca + critro       ovx        21.90
14        5       14             maca + critro       ovx        22.40
15        8       15 triple dosis maca + citro       ovx        18.90
16        8       16 triple dosis maca + citro       ovx        23.50
17        9       17 triple dosis maca + citro       ovx        24.50
18        9       18 triple dosis maca + citro       ovx        25.30
19        9       19 triple dosis maca + citro       ovx        27.90
20        9       20             sham operated    no ovx        25.50
21       10       21             sham operated    no ovx        23.40
22       10       22             sham operated    no ovx        22.50
23       10       23             sham operated    no ovx        22.90
   peso_final peso_utero    chol glucose    tag prot   urea album
1       33.28      0.089  85.990  109.97 182.42 5.37  66.27 66.82
2       30.50      0.063  94.460   81.62 211.87 4.68  76.73 55.36
3       29.93      0.078  99.670  118.37 195.16   NA  52.32    NA
4       32.19      0.134  83.380   71.91  98.46   NA  50.71    NA
5       30.37      0.052  82.080   95.53 108.13 5.33  26.02    NA
6       30.43      0.055 107.490  160.36 141.10   NA     NA 72.14
7       28.77      0.064  76.870  195.53  95.82 5.02  40.78 67.09
8       27.30      0.062  95.760  182.41 105.49 6.12  66.94 70.64
9       26.86      0.070  85.340  184.51  90.99   NA     NA 66.27
10      29.10      0.113  82.080  168.50 143.30 4.85  34.48 83.73
11      24.93      0.108  80.781  113.38 128.35   NA     NA    NA
12      26.70      0.022  88.590  102.62 282.64   NA     NA    NA
13      28.67      0.014 104.880   60.10 200.00 5.33  37.96    NA
14      28.37      0.046  70.350  150.13 199.12 4.93  45.61 64.64
15      23.80      0.057  78.170  110.50 114.73 4.78  38.23 52.77
16      26.70      0.065  85.340  144.88 134.51 5.15  43.06 59.59
17      28.77      0.016  64.400  138.85 160.44   NA     NA    NA
18      29.20      0.068  67.100  140.68 127.03   NA     NA    NA
19      29.48      0.076  65.790  114.70 169.67 6.17     NA    NA
20      30.27      0.088  74.260   94.23 185.05 4.93     NA 68.59
21      27.90      0.535  59.280  126.77 244.84   NA  60.37    NA
22      26.68      0.081  68.400   78.22  93.19   NA 157.89    NA
23      27.43      0.176  84.690  125.20 108.13   NA     NA    NA
  • ¿Qué pasa si no se sabe si el duplicado es erróneo?

    • Podemos tener dos o más filas con duplicados y no saber cuál es el correcto.

    • En estos casos, el problema es complejo. Una solución puede ser la deduplicación probabilística.

Paso 3: Identifique datos faltantes

  • Evalúe número y porcentaje de datos perdidos así como el patrón de estos.

  • Hay varios paquetes que permiten manejar datos perdidos:

    • {VIM}
    • {visdat}
    • {naniar}
    • {otros}
  • Usaremos algunas funciones de {visdat}, {VIM} y {naniar}.

  • {visdat} y {nanair} generan gráficos {ggplot2}, mientras que {VIM} no lo hace.

Paso 3: Identifique datos faltantes (cont.)

  • Nuevamente skim() nos permite conocer, rápidamente, el número de datos perdidos.
skim(datos)
Data summary
Name datos
Number of rows 23
Number of columns 13
_______________________
Column type frequency:
character 2
numeric 11
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
tratamiento 0 1 4 25 0 5 0
protocolo 0 1 3 7 0 3 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id_jaula 0 1.00 5.30 3.38 1.00 2.00 5.00 9.00 10.00 ▇▃▅▂▇
id_raton 0 1.00 12.00 6.78 1.00 6.50 12.00 17.50 23.00 ▇▆▇▆▇
peso_inicial 0 1.00 23.68 1.99 18.90 22.59 23.50 24.90 27.90 ▂▃▇▇▂
peso_final 0 1.00 28.59 2.18 23.80 27.08 28.77 30.10 33.28 ▂▆▇▅▂
peso_utero 0 1.00 0.09 0.10 0.01 0.06 0.07 0.09 0.54 ▇▁▁▁▁
chol 0 1.00 81.96 12.89 59.28 72.31 82.08 87.29 107.49 ▅▃▇▃▃
glucose 0 1.00 124.74 37.27 60.10 99.08 118.37 147.50 195.53 ▅▇▇▃▅
tag 0 1.00 153.06 52.36 90.99 108.13 141.10 190.11 282.64 ▇▃▅▁▂
prot 11 0.52 5.22 0.49 4.68 4.91 5.08 5.34 6.17 ▇▃▅▁▃
urea 9 0.61 56.95 32.34 26.02 38.87 48.16 64.80 157.89 ▇▃▁▁▁
album 12 0.48 66.15 8.44 52.77 62.12 66.82 69.62 83.73 ▃▃▇▂▂
  • El paquete visdat te permite visualizar el tipo de dato y si hay o no presencia de datos perdidos
library(visdat)
datos %>% 
  vis_dat()

  • Es importante verificar si el tipo de dato corresponde con la naturaleza de la variable de estudio.

  • Algunos datos faltantes pueden no verse por no configurar apropiadamente el tipo de la variable.

  • Podemos también generar gráficos para identificar los datos perdidos y sus combinaciones:
datos %>% 
  vis_miss()

  • Se aprecia que la variable prot tiene 47.83% de sus datos faltantes. La variable urea tiene 39.13% de sus datos faltantes.

  • La legenda que dice Missing (10.7%) indica que el total de datos faltantes en las celdas (no en las filas) es de 10.7%.

  • ¿Cuántos datos faltantes en por fila tendremos? ¿Qué combinaciones de datos faltantes tendremos?

  • El paquete VIM() permite identificar datos perdidos por variable y sus combinaciones.

  • Podemos visualizar los resultados directamente:

library(VIM)
datos %>% 
  aggr(numbers = TRUE)

  • También podemos usar la función gg_miss_upset del paquete {naniar} para evaluar las combinaciones de datos perdidos:
library(naniar)
datos %>% 
  gg_miss_upset()

  • Lo primero que uno debe tratar de hacer es recuperar los datos faltantes.

    • Volver a revisar documentos fuentes.

    • Recontactar sujetos, etc.

  • Podemos identificar a los individuos con datos faltantes en la variable urea usando filter():

datos %>% 
  select(id_jaula, id_raton, urea) %>% 
  filter(is.na(urea))
   id_jaula id_raton urea
6         2        6   NA
9         3        9   NA
11        5       11   NA
12        5       12   NA
17        9       17   NA
18        9       18   NA
19        9       19   NA
20        9       20   NA
23       10       23   NA
  • Si se recupera la información, uno puede remplazar los valores usando código en R.

  • La función replace del paquete {dplyr} es útil para esto. Supongamos que el dato perdido para el ratón 6 es de 65.2, podemos rempalzar el dato usando replace

datos %>% 
  select(id_jaula, id_raton, urea) %>% 
  mutate(
    urea = replace(urea, id_raton == 6, 65.2)
  )
   id_jaula id_raton   urea
1         1        1  66.27
2         1        2  76.73
3         1        3  52.32
4         2        4  50.71
5         2        5  26.02
6         2        6  65.20
7         2        7  40.78
8         3        8  66.94
9         3        9     NA
10        3       10  34.48
11        5       11     NA
12        5       12     NA
13        5       13  37.96
14        5       14  45.61
15        8       15  38.23
16        8       16  43.06
17        9       17     NA
18        9       18     NA
19        9       19     NA
20        9       20     NA
21       10       21  60.37
22       10       22 157.89
23       10       23     NA
  • Los datos perdidos a veces se guardan por defecto con algunos caracteres especiales.

  • Pueden ser problemáticas si se guardan con categorías como: -99, 8888, “No aplica”, “No sabe”, etc.

  • Una función muy útil para lidiar con estos datos y convertirlos en NA es la función replace_na() del paquete {tidyr}

library(tidyr)
datos_perdidos_comun
   edad diabetes
1    45       Sí
2    23       Sí
3    34       No
4    29      N/A
5  -999       No
6    23       Sí
7    34       No
8    57      N/A
9    88      N/A
10 -999      N/A
11 -999       Sí
  • Podemos convertir directamente todos estos valores por default a datos perdidos:
datos_perdidos_comun %>% 
  na_if(list(edad = -999, diabetes = "N/A")) -> datos_perdidos_limpia

datos_perdidos_limpia
   edad diabetes
1    45       Sí
2    23       Sí
3    34       No
4    29     <NA>
5    NA       No
6    23       Sí
7    34       No
8    57     <NA>
9    88     <NA>
10   NA     <NA>
11   NA       Sí

Paso 4: Identifique valores extremos no plausibles

  • Revise, variable por variable valores extremos no plausibles o plausibles, pero sospechosamente extremos. El valor mínimo es p0 y el valor máximo es p100. Deben ser plausibles.
skim(datos)
Data summary
Name datos
Number of rows 23
Number of columns 13
_______________________
Column type frequency:
character 2
numeric 11
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
tratamiento 0 1 4 25 0 5 0
protocolo 0 1 3 7 0 3 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id_jaula 0 1.00 5.30 3.38 1.00 2.00 5.00 9.00 10.00 ▇▃▅▂▇
id_raton 0 1.00 12.00 6.78 1.00 6.50 12.00 17.50 23.00 ▇▆▇▆▇
peso_inicial 0 1.00 23.68 1.99 18.90 22.59 23.50 24.90 27.90 ▂▃▇▇▂
peso_final 0 1.00 28.59 2.18 23.80 27.08 28.77 30.10 33.28 ▂▆▇▅▂
peso_utero 0 1.00 0.09 0.10 0.01 0.06 0.07 0.09 0.54 ▇▁▁▁▁
chol 0 1.00 81.96 12.89 59.28 72.31 82.08 87.29 107.49 ▅▃▇▃▃
glucose 0 1.00 124.74 37.27 60.10 99.08 118.37 147.50 195.53 ▅▇▇▃▅
tag 0 1.00 153.06 52.36 90.99 108.13 141.10 190.11 282.64 ▇▃▅▁▂
prot 11 0.52 5.22 0.49 4.68 4.91 5.08 5.34 6.17 ▇▃▅▁▃
urea 9 0.61 56.95 32.34 26.02 38.87 48.16 64.80 157.89 ▇▃▁▁▁
album 12 0.48 66.15 8.44 52.77 62.12 66.82 69.62 83.73 ▃▃▇▂▂
  • Permite hacer algo similar
describe(datos)
datos 

 13  Variables      23  Observations
--------------------------------------------------------------------------------
id_jaula : ID de jaula 
       n  missing distinct     Info     Mean      Gmd 
      23        0        7    0.979    5.304    3.881 

lowest :  1  2  3  5  8, highest:  3  5  8  9 10
                                                    
Value          1     2     3     5     8     9    10
Frequency      3     4     3     4     2     4     3
Proportion 0.130 0.174 0.130 0.174 0.087 0.174 0.130
--------------------------------------------------------------------------------
id_raton : ID de ratón 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       23        1       12        8      2.1      3.2 
     .25      .50      .75      .90      .95 
     6.5     12.0     17.5     20.8     21.9 

lowest :  1  2  3  4  5, highest: 19 20 21 22 23
--------------------------------------------------------------------------------
tratamiento : Tratamiento asignado 
       n  missing distinct 
      23        0        5 

lowest : control                   maca                      maca + critro             sham operated             triple dosis maca + citro
highest: control                   maca                      maca + critro             sham operated             triple dosis maca + citro

control (5, 0.217), maca (5, 0.217), maca + critro (4, 0.174), sham operated
(4, 0.174), triple dosis maca + citro (5, 0.217)
--------------------------------------------------------------------------------
protocolo : Tipo de protocolo de modelo animal 
       n  missing distinct 
      23        0        3 
                                  
Value      hemiovx  no ovx     ovx
Frequency        2       4      17
Proportion   0.087   0.174   0.739
--------------------------------------------------------------------------------
peso_inicial : Peso inicial 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       19    0.998    23.68    2.244    20.55    21.90 
     .25      .50      .75      .90      .95 
   22.59    23.50    24.90    25.90    26.53 

lowest : 18.90 20.40 21.90 22.40 22.50, highest: 25.30 25.50 26.00 26.59 27.90
                                                                            
Value      18.90 20.40 21.90 22.40 22.50 22.69 22.90 23.20 23.40 23.50 23.90
Frequency      1     1     2     1     1     1     1     1     2     2     1
Proportion 0.043 0.043 0.087 0.043 0.043 0.043 0.043 0.043 0.087 0.087 0.043
                                                          
Value      24.50 24.80 25.00 25.30 25.50 26.00 26.59 27.90
Frequency      2     1     1     1     1     1     1     1
Proportion 0.087 0.043 0.043 0.043 0.043 0.043 0.043 0.043
--------------------------------------------------------------------------------
peso_final : Peso final 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       21    0.999    28.59    2.483    25.11    26.68 
     .25      .50      .75      .90      .95 
   27.08    28.77    30.10    30.49    32.02 

lowest : 23.80 24.93 26.68 26.70 26.86, highest: 30.37 30.43 30.50 32.19 33.28
--------------------------------------------------------------------------------
peso_utero : Peso uterino 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       23        1   0.0927  0.07728   0.0166   0.0268 
     .25      .50      .75      .90      .95 
  0.0560   0.0680   0.0885   0.1298   0.1718 

lowest : 0.014 0.016 0.022 0.046 0.052, highest: 0.108 0.113 0.134 0.176 0.535
--------------------------------------------------------------------------------
chol : Colesterol 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       21    0.999    81.96     14.9    64.54    66.05 
     .25      .50      .75      .90      .95 
   72.31    82.08    87.29    98.89   104.36 

lowest :  59.28  64.40  65.79  67.10  68.40, highest:  94.46  95.76  99.67 104.88 107.49
--------------------------------------------------------------------------------
glucose : Glucosa 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       23        1    124.7    43.44    72.54    78.90 
     .25      .50      .75      .90      .95 
   99.08   118.37   147.50   179.63   184.30 

lowest :  60.10  71.91  78.22  81.62  94.23, highest: 160.36 168.50 182.41 184.51 195.53
--------------------------------------------------------------------------------
tag : Triglicéridos 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       22        1    153.1    59.41    93.45    96.35 
     .25      .50      .75      .90      .95 
  108.13   141.10   190.11   209.50   241.54 

lowest :  90.99  93.19  95.82  98.46 105.49, highest: 199.12 200.00 211.87 244.84 282.64
--------------------------------------------------------------------------------
prot : Proteína 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      12       11       10    0.993    5.222   0.5367    4.735    4.787 
     .25      .50      .75      .90      .95 
   4.910    5.085    5.340    6.045    6.143 

lowest : 4.68 4.78 4.85 4.93 5.02, highest: 5.15 5.33 5.37 6.12 6.17
                                                                      
Value       4.68  4.78  4.85  4.93  5.02  5.15  5.33  5.37  6.12  6.17
Frequency      1     1     1     2     1     1     2     1     1     1
Proportion 0.083 0.083 0.083 0.167 0.083 0.083 0.167 0.083 0.083 0.083
--------------------------------------------------------------------------------
urea : Urea 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      14        9       14        1    56.95    30.41    31.52    35.52 
     .25      .50      .75      .90      .95 
   38.87    48.16    64.80    73.79   105.14 

lowest :  26.02  34.48  37.96  38.23  40.78, highest:  60.37  66.27  66.94  76.73 157.89
                                                                         
Value       26.02  34.48  37.96  38.23  40.78  43.06  45.61  50.71  52.32
Frequency       1      1      1      1      1      1      1      1      1
Proportion  0.071  0.071  0.071  0.071  0.071  0.071  0.071  0.071  0.071
                                             
Value       60.37  66.27  66.94  76.73 157.89
Frequency       1      1      1      1      1
Proportion  0.071  0.071  0.071  0.071  0.071
--------------------------------------------------------------------------------
album : Albuminemia 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      11       12       11        1    66.15    9.592    54.06    55.36 
     .25      .50      .75      .90      .95 
   62.12    66.82    69.62    72.14    77.94 

lowest : 52.77 55.36 59.59 64.64 66.27, highest: 67.09 68.59 70.64 72.14 83.73
                                                                            
Value      52.77 55.36 59.59 64.64 66.27 66.82 67.09 68.59 70.64 72.14 83.73
Frequency      1     1     1     1     1     1     1     1     1     1     1
Proportion 0.091 0.091 0.091 0.091 0.091 0.091 0.091 0.091 0.091 0.091 0.091
--------------------------------------------------------------------------------
  • El gráfico de cajas nos muestra la disrtibución de la variable numérica en termino de sus cuantiles.

  • Los puntos aislados, fuera de las cajas y bigotes, son considerados valores extremos.

  • Estos pueden ser plausibles o no plausibles.

  • El gráfico de cajas permite identificar, rápidamente, valores extremos potencialmente no plausibles o problemáticos.

boxplot(datos$peso_final)

boxplot(datos$peso_utero)

  • Los datos extremos pueden ser valores anómalos válidos.

  • En ocasiones, son valores no plausibles, inválidos, producto del mal recojo de información.

  • Cuando se tenga valores extremos no plausibles se puede optar por dos acciones:

      1. Corregir el valor extremo no plausible por datos que sí sean plausibles.
      1. Si no se puede, convertir los valores extremos no plausibles en datos faltantes (veremos esto).
      1. Bonus: A veces puede ser mejor recortar los datos y quedarse con el 1% y 99% percentil más bajo y alto, respectivamente.
  • Se puede usar la función: na_if() del paquete {dplyr}.
  • Veamos una base de datos juguete con datos de peso (kg) y hemoglobina (mg/dL) de pacientes en un estudio:

    • El peso de 1450 es un valor extremo no plausible. Igualmente, los valores de hemoglobina 213, 3124 y -4 son valores extremos no plausibles.

    • Lo primero que debemos hacer es recuperar es tratar de recuperar estos valores.

    • Supongamos que podemos recuperar los valores: 1450 en realidad es 45 kg; 213, 3124 y -4 son 11.3, 10.44 y 9.2 mg/dL.

  • Podemos usar la función recode para corregir los valores de peso:

datos_extremo %>% 
  mutate(peso = recode(peso, `1450` = 45))
  peso   hb
1   56   12
2   34   11
3   23  213
4   78   10
5   46 3124
6   45   -4
  • También podemos corregir de varias variables simultáneamente:
datos_extremo %>% 
  mutate(
    peso = recode(peso, `1450` = 45), 
    hb = recode(hb, `213` = 11.3, `3124` = 10.44, `-4` = 9.2)
    ) -> datos_extremo_recodif

datos_extremo_recodif
  peso    hb
1   56 12.00
2   34 11.00
3   23 11.30
4   78 10.00
5   46 10.44
6   45  9.20
  • Si no podemos recuperar los datos correctos, la otra opción es convertir los valores extremos en datos faltantes:
datos_extremo %>% 
  mutate(
    peso = na_if(peso, 1450)
  )
  peso   hb
1   56   12
2   34   11
3   23  213
4   78   10
5   46 3124
6   NA   -4
  • Podemos hacerlo de manera simultánea para varias variables
datos_extremo %>% 
  mutate(
    peso = na_if(peso, 1450), 
    hb = na_if(hb, 213), 
    hb = na_if(hb, 3124), 
    hb = na_if(hb, -4)
  )
  peso hb
1   56 12
2   34 11
3   23 NA
4   78 10
5   46 NA
6   NA NA
  • O usando replace() y una condición lógica:
datos_extremo %>% 
  mutate(
    peso = na_if(peso, 1450), 
    hb = replace(hb, hb > 100 | hb < 0, NA)
  ) -> datos_extremo_recomiss

datos_extremo_recomiss
  peso hb
1   56 12
2   34 11
3   23 NA
4   78 10
5   46 NA
6   NA NA

Paso 5: Detecte y corrija inconsistencias mediante consultas (queries) de interés

Muestre el peso inicial mínimo, máximo y promedio del grupo control:

datos %>% 
  filter(tratamiento == "control") %>% 
  summarise(
    minimo_peso = min(peso_inicial), 
    maximo_peso = max(peso_inicial), 
    promedio_peso = mean(peso_inicial)
  )
  minimo_peso maximo_peso promedio_peso
1        20.4       26.59        24.198

Muestre los pesos inicial máximos, mínimo y promedio según grupo de tratamiento. También muestre el número de ratones por grupo:

datos %>% 
  group_by(tratamiento) %>% 
  summarise(
    minimo_peso = min(peso_inicial), 
    maximo_peso = max(peso_inicial), 
    promedio_peso = mean(peso_inicial), 
    n_ratones = n()
  )
# A tibble: 5 × 5
  tratamiento               minimo_peso maximo_peso promedio_peso n_ratones
  <chr>                           <dbl>       <dbl>         <dbl>     <int>
1 control                          20.4        26.6          24.2         5
2 maca                             22.7        25            23.9         5
3 maca + critro                    21.9        23.4          22.4         4
4 sham operated                    22.5        25.5          23.6         4
5 triple dosis maca + citro        18.9        27.9          24.0         5

Muestre los id_jaula con el número de ratones por jaula

datos %>% 
  group_by(id_jaula) %>% 
  summarise(n_ratones_por_jaula = n())
# A tibble: 7 × 2
  id_jaula n_ratones_por_jaula
     <dbl>               <int>
1        1                   3
2        2                   4
3        3                   3
4        5                   4
5        8                   2
6        9                   4
7       10                   3

Identifique los ID de los ratones del grupo control con una razón glucosa / colesterol > 1

datos %>% 
  filter(tratamiento == "control" & glucose / chol > 1)
  id_jaula id_raton tratamiento protocolo peso_inicial peso_final peso_utero
1        1        1     control       ovx         26.0      33.28      0.089
3        1        3     control       ovx         20.4      29.93      0.078
5        2        5     control       ovx         23.5      30.37      0.052
   chol glucose    tag prot  urea album
1 85.99  109.97 182.42 5.37 66.27 66.82
3 99.67  118.37 195.16   NA 52.32    NA
5 82.08   95.53 108.13 5.33 26.02    NA

Otra forma de hacerlo, es crear primerio la razón glucose / chol y filtrar:

datos %>% 
  mutate(ratio_gluc_chol = glucose / chol) %>% 
  filter(tratamiento == "control" & ratio_gluc_chol > 1)
  id_jaula id_raton tratamiento protocolo peso_inicial peso_final peso_utero
1        1        1     control       ovx         26.0      33.28      0.089
3        1        3     control       ovx         20.4      29.93      0.078
5        2        5     control       ovx         23.5      30.37      0.052
   chol glucose    tag prot  urea album ratio_gluc_chol
1 85.99  109.97 182.42 5.37 66.27 66.82        1.278870
3 99.67  118.37 195.16   NA 52.32    NA        1.187619
5 82.08   95.53 108.13 5.33 26.02    NA        1.163865

Nuestro turno


  • Descargue la carpeta aid.

  • Abra el proyecto aid.Rproj y dentro de este, abra el archivo quarto aid_taller.qmd.

  • Siga las instrucciones indicadas en este.

  • Renderice el archivo quarto final.




10:00